#include <iostream>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

int ticket = 1000;
// 锁的定义有两种方式,全局和局部
// 两种定义的初始化方式和销毁不同

// 定义为全局锁需要直接赋值PTHREAD_MUTEX_INITIALIZER,不需要init和destroy,生命随进程
// pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

// 定义为局部不需要赋值,要使用init和destroy
pthread_mutex_t mutex;
void *Ticket(void *args)
{
    std::string name = static_cast<const char *>(args);
    // 在访问公共资源前就要加锁
    while (true)
    {
        usleep(1000);
        pthread_mutex_lock(&mutex);
        if (ticket > 0)
        {
            std::cout << name << "get a ticket,ticket::" << --ticket << "张" << std::endl;
            // 访问完毕要解锁
            pthread_mutex_unlock(&mutex);
        }
        else 
        {
            //没票就结束
            pthread_mutex_unlock(&mutex);
            break;
        }
    }
    return nullptr;
}

int main()
{
    pthread_mutex_init(&mutex, nullptr);
    pthread_t th1, th2, th3, th4;
    // 4个线程重入Ticket函数并访问公共资源,要对公共资源的访问加锁保护
    pthread_create(&th1, nullptr, Ticket, (void *)"thread-1");
    pthread_create(&th2, nullptr, Ticket, (void *)"thread-2");
    pthread_create(&th3, nullptr, Ticket, (void *)"thread-3");
    pthread_create(&th4, nullptr, Ticket, (void *)"thread-4");
    pthread_join(th1, nullptr);
    pthread_join(th1, nullptr);
    pthread_join(th1, nullptr);
    pthread_join(th1, nullptr);
    pthread_mutex_destroy(&mutex);
    return 0;
}